package GUI;

import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;

import javax.swing.AbstractButton;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JRadioButton;
import javax.swing.ButtonGroup;
import java.lang.Math;
import java.util.ArrayList;

import javax.swing.JCheckBox;
import javax.swing.filechooser.FileNameExtensionFilter;

import Database.Article;
import Database.Author;
import Database.Book;
import Database.OracleConnection;
import Database.Paper;
import Database.SolutionForView;
import Parser.BibtexDirectory;
import Parser.BibtexFile;

class Relations
{
	private String name; // numele autorului
	private String[] colabs; // numele colaboratorului
	private int[] pcomm; // numarul de lucrari in comun cu colaboratorul din
	// colabs[i]
	private int nr; // numarul de colaboratori

	public Relations(String name, int tip_colab)
	{
		SolutionForView sol = OracleConnection.selectResult(name, tip_colab + 1);
		this.setName(name);

		if (tip_colab == 0)
		{
			nr = sol.getColabsBooks().size();
			colabs = new String[sol.getColabsBooks().size()];
			pcomm = new int[sol.getColabsBooks().size()];
			int i = 0;
			for (String s : sol.getColabsBooks())
				colabs[i ++] = s;
			i = 0;
			for (Integer nr : sol.getPcommBooks())
				pcomm[i ++] = nr.intValue();
		}

		if (tip_colab == 1)
		{
			nr = sol.getColabsArticles().size();
			colabs = new String[sol.getColabsArticles().size()];
			pcomm = new int[sol.getColabsArticles().size()];
			int i = 0;
			for (String s : sol.getColabsArticles())
				colabs[i ++] = s;
			i = 0;
			for (Integer nr : sol.getPcommArticles())
				pcomm[i ++] = nr.intValue();
		}
		
		if (tip_colab == 2)
		{
			nr = sol.getCombined().size();
			colabs = new String[sol.getCombined().size()];
			pcomm = new int[sol.getCombined().size()];
			int i = 0;
			for (String s : sol.getCombined())
				colabs[i ++] = s;
			i = 0;
			for (Integer nr : sol.getpCombined())
				pcomm[i ++] = nr.intValue();
		}
	}

	public int get_max()
	{
		int max = 0;
		for (int i = 0; i < nr; i++)
			if (pcomm[i] > max)
				max = pcomm[i];
		return max;
	}

	public int colab_no()
	{
		return nr;
	}

	public String[] get_colabs()
	{
		return this.colabs;
	}

	public int[] get_pcomm()
	{
		return this.pcomm;
	}

	public void setName(String name)
	{
		this.name = name;
	}

	public String getName()
	{
		return name;
	}
}

public class RelationGraph extends Applet implements MouseListener,
		MouseMotionListener, ActionListener, Runnable
{
	/**
	 * 
	 */
	
	public String directory = "F:\\Codrut\\Facultate\\SISD\\Vizualizarea relatiilor de colaborare";

	private static final long serialVersionUID = 1L;
	TextField consola;
	Label label1;
	JCheckBox cb;
	JRadioButton bcarti, barticole, bambele;
	Button bParseDirectory;

	int ymd, xmd; // dimensiunei foii de lucru
	int xm, ym; // coordonatele centrului poligonului
	int[] xpoints, ypoints; // variabile de manevra pentru varfurile
	// poligoanelor in constructie
	int npoints; // variabila de manevra pentru nr varfurilor poligoanelor in
	// constructie
	String[] colabs;
	int[] pcomm;
	int unitate;
	String cname;

	class KeyHandler extends KeyAdapter
	{
		public void keyPressed(KeyEvent e)
		{
			if (e.getKeyChar() == KeyEvent.VK_ENTER)
			{
				String text = consola.getText();
				int tip_colab = 2; // ambele tipuri de colaborari
				if (barticole.isSelected())
					tip_colab = 0;// doar articole
				else if (bcarti.isSelected())
					tip_colab = 1;// doar carti
				Relations rel = new Relations(text, tip_colab);
				cname = text;
				npoints = rel.colab_no();
				colabs = rel.get_colabs();
				pcomm = rel.get_pcomm();
				xpoints = new int[npoints];
				ypoints = new int[npoints];
				int alfa;
				if (npoints == 0)
					alfa=360;
				else
					alfa = 360 / npoints;
				if (rel.get_max()==0)
					unitate=1;
				else
				{
					unitate = (ymd-10) / (2 * rel.get_max());
					if ((xmd-10) / (2 * rel.get_max())< unitate)
						unitate=(xmd-10) / (2 * rel.get_max());
				}
				for (int i = 0; i < rel.colab_no(); i++)
				{
					int alfai = i * alfa;
					xpoints[i] = (int) (xmd / 2 + (pcomm[i] * unitate * Math
							.sin(alfai * (3.14) / 180)));
					ypoints[i] = (int) (ymd / 2 + (pcomm[i] * unitate * Math
							.cos(alfai * (3.14) / 180)));
				}

				repaint();
			}
		}
	}
	
	private class ButtonActionListener implements ActionListener
	{
		private RelationGraph rg;
		
		public ButtonActionListener(RelationGraph rg)
		{
			this.rg = rg;
		}

		@Override
		public void actionPerformed(ActionEvent arg0)
		{
			JFileChooser chooser = new JFileChooser();
			chooser.setCurrentDirectory(new java.io.File("."));
		    chooser.setDialogTitle("Select directory");
		    chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
			int returnVal = chooser.showOpenDialog(rg);
			String dirName = "";
			if (returnVal == JFileChooser.APPROVE_OPTION)
			{
				dirName = chooser.getSelectedFile().getAbsolutePath();
				System.out.println("You chose to open this file: "
						+ chooser.getSelectedFile().getAbsolutePath());
			}
			
			BibtexDirectory dir = new BibtexDirectory(dirName);
			ArrayList<Paper> list = dir.getPaperList();
			
			for (Paper paper : list)
			{
				OracleConnection.insertIntoDB(paper);
				
				if (paper instanceof Book)
					System.out.println("Titlu=" + paper.titlu + " Editura=" + ((Book) paper).editura);
				else
					System.out.println("Titlu=" + paper.titlu + " Revista=" + ((Article) paper).publicatie);
				
				System.out.print("Autori=");
				for (Author author : paper.getAuthorsList())
					System.out.print(author.nume + " " + author.contact + ";");
				System.out.println();
			}
		}
	}

	@SuppressWarnings("deprecation")
	public void init()
	{
		OracleConnection.getOracleConnection1();
		OracleConnection.getOracleConnection2();
		
		setLayout(null);

		// dimensionare zone
		Dimension d = getSize();
		xmd = d.width * 2 / 3;
		ymd = d.height;
		xm = xmd / 2;
		ym = ymd / 2;
		
		npoints=-1;

		Container c2 = new Container();
		c2.setLayout(new GridLayout(1, 1));
		c2.setBounds(xmd, 0, xmd / 2, ymd / 16);
		label1 = new Label("Introduceti autorul:");
		c2.add(label1);
		label1.setBackground(Color.white);
		label1.setForeground(Color.black);
		add(c2);

		consola = new TextField();
		consola.setBounds(xmd, ymd / 16, xmd / 2, ymd / 16);
		consola.addKeyListener(new KeyHandler());
		add(consola);
		consola.show();

		Container c = new Container();
		c.setLayout(new GridLayout(4, 1));
		bParseDirectory = new Button("Parsare Director");
		bcarti = new JRadioButton("Carti");
		barticole = new JRadioButton("Articole");
		bambele = new JRadioButton("Carti si articole");
		bambele.setSelected(true);

		// Group the radio buttons.
		ButtonGroup group = new ButtonGroup();
		group.add(bcarti);
		group.add(barticole);
		group.add(bambele);

		// Register a listener for the radio buttons.
		bcarti.addActionListener(this);
		barticole.addActionListener(this);
		bambele.addActionListener(this);

		c.setBounds(xmd, ymd / 4, 3 * xmd / 4, ymd / 4);
		c.add(bcarti);
		Label l1 = new Label("______");
		l1.setForeground(Color.blue);
		c.add(l1);
		c.add(barticole);
		Label l2 = new Label("______");
		l2.setForeground(Color.black);
		c.add(l2);
		c.add(bambele);
		Label l3 = new Label("______");
		l3.setForeground(Color.red);
		c.add(l3);
		add(c);

		Container c1 = new Container();
		c1.setLayout(new GridLayout(3, 1));
		cb = new JCheckBox("Grid aproximare", null, false);
		c1.setBounds(xmd, 5 * ymd / 8, xmd / 2, ymd / 8);
		c1.add(cb);
		add(c1);
		
		Container c3= new Container();
		c3.setLayout(new GridLayout(1, 1));
		bParseDirectory.addActionListener(new ButtonActionListener(this));
		c3.add(bParseDirectory);
		c3.setBounds(xmd, 6 * ymd / 8, xmd / 3, ymd / 16);
		add(c3);
		
		
		addMouseListener(this);
		addMouseMotionListener(this);
	}

	public void paint(Graphics g)
	{
		g.clearRect(0, 0, xmd, ymd);
		label1.setVisible(true);
		if (barticole.isSelected())
			g.setColor(Color.black);
		else if (bcarti.isSelected())
			g.setColor(Color.blue);
		else
			g.setColor(Color.red);
		g.drawOval(xmd / 2 - 2, ymd / 2 - 3, 6, 6);
		g.fillOval(xmd / 2 - 2, ymd / 2 - 3, 6, 6);
		if (cb.isSelected())
		{
			g.setColor(Color.green);
			int n = 10;
			for (int i = 0; i < xmd / (20 * unitate); i++)
			{
				g.drawOval(xmd / 2 - unitate * n, ymd / 2 - unitate * n, 2
						* unitate * n, 2 * unitate * n);
				n = n + 10;
			}
			if (barticole.isSelected())
				g.setColor(Color.black);
			else if (bcarti.isSelected())
				g.setColor(Color.blue);
			else
				g.setColor(Color.red);
		} else
		{
			g.setColor(Color.white);
			int n = 10;
			if (unitate == 0)
				unitate = 1;
			for (int i = 0; i < xmd / (20 * unitate); i++)
			{
				g.drawOval(xmd / 2 - unitate * n, ymd / 2 - unitate * n, 2
						* unitate * n, 2 * unitate * n);
				n = n + 10;
			}
			if (barticole.isSelected())
				g.setColor(Color.black);
			else if (bcarti.isSelected())
				g.setColor(Color.blue);
			else
				g.setColor(Color.red);
		}
		for (int i = 0; i < npoints; ++i)
		{
			g.drawString(cname, xmd / 2 + 6, ymd / 2 + 6);
			g.drawLine(xmd / 2, ymd / 2, xpoints[i], ypoints[i]);
			g.drawOval(xpoints[i] - 3, ypoints[i] - 3, 6, 6);
			g.fillOval(xpoints[i] - 3, ypoints[i] - 3, 6, 6);
			g.drawString(colabs[i], xpoints[i]-20, ypoints[i] + 12);
		}
		if (npoints==0)
			g.drawString("Autorul nu exista in baza de date", xmd / 2 + 8, ymd / 2 + 6);

	}

	public void processMouseEvent(MouseEvent me)
	{
		super.processMouseEvent(me);
		repaint();
	}

	public void mouseClicked(MouseEvent me)
	{
		/*
		 * relations rel=new relations(consola.getText()); String txt="";
		 * txt.concat(rel.colab_no()+"\n"); String[] colabs=rel.get_colabs();
		 * int[] pcomm=rel.get_pcomm(); for (int i=0;i<rel.colab_no();i++) {
		 * txt.concat(colabs[i]+" "+pcomm[i]+"\n"); } consola.setText(txt);
		 */

		repaint();
	}

	public void mousePressed(MouseEvent me)
	{
	}

	public void mouseDragged(MouseEvent me)
	{
	}

	public void mouseMoved(MouseEvent me)
	{
	}

	public void mouseEntered(MouseEvent me)
	{
	}

	public void mouseExited(MouseEvent me)
	{
	}

	public void mouseReleased(MouseEvent me)
	{
	}

	public void actionPerformed(ActionEvent e)
	{
		/*
		 * se preiau comenzi de la meniu String text = consola.getText();
		 * relations rel=new relations(text); npoints=rel.colab_no(); String[]
		 * colabs=rel.get_colabs(); int[] pcomm=rel.get_pcomm(); xpoints=new
		 * int[npoints]; ypoints=new int[npoints]; int alfa=360/npoints; for
		 * (int i=0;i<rel.colab_no();i++) { int alfai=i*alfa;
		 * xpoints[i]=(int)(xmd/2+Math.sqrt(alfai));
		 * ypoints[i]=(int)(ymd/2+Math.sqrt(alfai/Math.tan(alfai))); }
		 */
		
		AbstractButton aButton = (AbstractButton) e.getSource();
        if (aButton.getText()== "Articole" || aButton.getText()== "Carti" || aButton.getText()== "Carti si articole" )
        {
		        String text = consola.getText();
				int tip_colab=2;
				if (aButton.getText()=="Articole")
					tip_colab = 0;// doar articole
				else if (aButton.getText()=="Carti")
					tip_colab = 1;// doar carti
				Relations rel = new Relations(text, tip_colab);
				cname = text;
				npoints = rel.colab_no();
				colabs = rel.get_colabs();
				pcomm = rel.get_pcomm();
				xpoints = new int[npoints];
				ypoints = new int[npoints];
				int alfa;
				if (npoints == 0)
					alfa=360;
				else
					alfa = 360 / npoints;
				if (rel.get_max()==0)
					unitate=0;
				else
				{
					unitate = (ymd-10) / (2 * rel.get_max());
					if ((xmd-10) / (2 * rel.get_max())< unitate)
						unitate=(xmd-10) / (2 * rel.get_max());
				}
				for (int i = 0; i < rel.colab_no(); i++)
				{
					int alfai = i * alfa;
					xpoints[i] = (int) (xmd / 2 + (pcomm[i] * unitate * Math
							.sin(alfai * (3.14) / 180)));
					ypoints[i] = (int) (ymd / 2 + (pcomm[i] * unitate * Math
							.cos(alfai * (3.14) / 180)));
				}
		   }
        if (aButton.getText()== "Grid aproximare")
        	repaint();
        
		repaint();
	}

	public void update(Graphics g)
	{
		paint(g);
	}

	public void run()
	{
	}
	
}
